package bll

import (
	"fmt"
	"jgt-oper/src/model"
	"jgt-oper/src/schema"
	"jgt-oper/src/util"
	"strings"
	"sync"
	"time"

	"github.com/pkg/errors"
)

// Dictionary 字典表管理
type Dictionary struct {
	sync.RWMutex
	DictionaryModel model.IDictionary `inject:"IDictionary"`
}

// GetLevelCode 获取分级码
func (a *Dictionary) GetLevelCode(parentID string) (string, error) {
	a.Lock()
	defer a.Unlock()

	items, err := a.DictionaryModel.QueryByParentIDOrderLevelCode(parentID)
	if err != nil {
		return "", err
	} else if len(items) == 0 {
		if parentID == "" {
			return "001", nil
		}
		item, verr := a.Get(parentID)
		if verr != nil {
			return "", verr
		} else if item == nil {
			return "", errors.New("无效的上级")
		}
		return item.LevelCode + "001", nil
	}

	levelCode := items[0].LevelCode
	root := levelCode[:len(levelCode)-3]
	toValue := func(i int) string {
		if i < 10 {
			return fmt.Sprintf("%s00%d", root, i)
		}
		if i > 10 && i < 100 {
			return fmt.Sprintf("%s0%d", root, i)
		}
		return fmt.Sprintf("%s%d", root, i)
	}

	for i, l := 1, len(items); i < 1000; i++ {
		code := toValue(i)
		if i <= l &&
			items[i-1].LevelCode == code {
			continue
		}
		return code, nil
	}

	return "", errors.New("获取分级码发生错误")
}

// QueryPage 查询分页数据
func (a *Dictionary) QueryPage(params schema.DictionaryQueryParam, pageIndex, pageSize uint) (int64, []*schema.Dictionary, error) {
	return a.DictionaryModel.QueryPage(params, pageIndex, pageSize)
}

// QueryTree 查询树形数据
func (a *Dictionary) QueryTree(root string, level int, show ...bool) ([]map[string]interface{}, error) {
	var (
		codes               []string
		item                *schema.Dictionary
		data                []*schema.Dictionary
		err                 error
		mapItems, treeItems []map[string]interface{}
	)
	if root != "" {
		codes = strings.Split(root, "$#")
		item, err = a.DictionaryModel.GetByCode(codes)
		if err != nil {
			return nil, err
		}

		data, err = a.DictionaryModel.QueryChildsByLevelCode(item.LevelCode, level)
		if err != nil {
			return nil, err
		}
	} else {
		data, err = a.DictionaryModel.QueryChildsByLevelCode("", level)
		if err != nil {
			return nil, err
		}
	}

	if len(show) > 0 && show[0] {
		for _, v := range data {
			s := a.getshow(v)
			mapItems = append(mapItems, util.StructToMap(s))
		}

		treeItems = util.Slice2Tree(mapItems, "record_id", "parent_id")
		return util.ConvertToViewTree(treeItems, "name", "record_id", "record_id"), nil
	}
	for _, v := range data {
		mapItems = append(mapItems, util.StructToMap(v))
	}

	treeItems = util.Slice2Tree(mapItems, "record_id", "parent_id")
	return util.ConvertToViewTree(treeItems, "name", "record_id", "record_id"), nil

}

// QuerySimpleTree 查询简略树形数据
func (a *Dictionary) QuerySimpleTree(root string, level int) ([]map[string]interface{}, error) {
	var (
		codes               []string
		item                *schema.Dictionary
		data                []*schema.Dictionary
		err                 error
		mapItems, treeItems []map[string]interface{}
	)
	if root != "" {
		codes = strings.Split(root, "$#")
		item, err = a.DictionaryModel.GetByCode(codes)
		if err != nil {
			return nil, err
		}

		data, err = a.DictionaryModel.QueryChildsByLevelCode(item.LevelCode, level)
		if err != nil {
			return nil, err
		}
	} else {
		data, err = a.DictionaryModel.QueryChildsByLevelCode("", level)
		if err != nil {
			return nil, err
		}
	}

	for _, v := range data {
		mapItems = append(mapItems, util.StructToMap(v))
	}

	treeItems = util.Slice2Tree(mapItems, "record_id", "parent_id")
	return util.ConvertToSimpleViewTree(treeItems, "code", "code", "name", "name", "children"), nil

}

// getshow 获取展示
func (a *Dictionary) getshow(data *schema.Dictionary) *schema.DictionaryShow {
	show := new(schema.DictionaryShow)
	show.Code = data.Code
	show.ParentID = data.ParentID
	show.Name = data.Name
	show.RecordID = data.RecordID

	return show
}

// QueryList 条件查询数据列表
func (a *Dictionary) QueryList(params schema.DictionarySelectParam) ([]*schema.DictionarySelect, error) {
	return a.DictionaryModel.QuerySelect(params)
}

// Get 精确查询数据
func (a *Dictionary) Get(recordID string) (*schema.Dictionary, error) {
	return a.DictionaryModel.Get(recordID)
}

// GetByCode 根据code精确查询
func (a *Dictionary) GetByCode(code string) (*schema.Dictionary, error) {
	var (
		codes []string
		item  *schema.Dictionary
		err   error
	)
	codes = strings.Split(code, "$#")
	item, err = a.DictionaryModel.GetByCode(codes)

	return item, err
}

// Create 创建数据
func (a *Dictionary) Create(item *schema.Dictionary) error {

	levelCode, err := a.GetLevelCode(item.ParentID)
	if err != nil {
		return err
	}
	//	ind := item.Sequence
	item.LevelCode = levelCode
	item.ID = 0
	item.RecordID = util.UUID()
	item.Created = time.Now().Unix()
	item.Deleted = 0
	//	item.Sequence = a.GetLastSequence(item.ParentID) + 1
	err = a.DictionaryModel.Create(item)
	if err != nil {
		return err
	}
	//	if ind > 0 {
	//		err = a.ChangeSequence(item.ParentID, item.Sequence, ind)
	//	}
	return err

}

// Update 更新数据
func (a *Dictionary) Update(recordID string, item *schema.Dictionary) error {

	oldItem, err := a.Get(recordID)
	if err != nil {
		return err
	} else if oldItem == nil {
		return nil
	}

	// 优先更新分级码
	if item.ParentID != oldItem.ParentID {
		levelCode, verr := a.GetLevelCode(item.ParentID)
		if verr != nil {
			return verr
		}

		verr = a.DictionaryModel.UpdateLevelCode(oldItem.LevelCode, levelCode)
		if verr != nil {
			return verr
		}
	}

	info := util.StructToMap(item)
	delete(info, "id")
	delete(info, "record_id")
	//	delete(info, "sequence")
	delete(info, "creator")
	delete(info, "created")
	delete(info, "deleted")
	delete(info, "level_code")

	//	err = a.ChangeSequence(item.ParentID, oldItem.Sequence, item.Sequence)
	//	if err != nil {
	//		return err
	//	}

	return a.DictionaryModel.Update(recordID, info)

}

// Delete 删除数据
func (a *Dictionary) Delete(recordID string) error {
	var (
		exists bool
		//item   *schema.Dictionary
		err error
	)
	exists, err = a.DictionaryModel.CheckChild(recordID)
	if err != nil {
		return err
	} else if exists {
		return errors.New("含有下级字典表，不能删除")
	}
	//调整排序
	//	item, err = a.Get(recordID)
	//	if err != nil {
	//		return err
	//	}
	//	ind := a.GetLastSequence(item.ParentID)
	//	err = a.ChangeSequence(item.ParentID, item.Sequence, ind)
	//	if err != nil {
	//		return err
	//	}

	return a.DictionaryModel.Delete(recordID)
}

// QueryByIDs 根据ID列表查询菜单数据
func (a *Dictionary) QueryByIDs(recordIDs []string) ([]*schema.Dictionary, error) {
	return a.DictionaryModel.QueryByIDs(recordIDs)
}

// ChangeSequence 移动排序
func (a *Dictionary) ChangeSequence(parentID string, from, to int) error {

	info := map[string]interface{}{
		"parent_id": parentID,
	}
	list := util.IndexMove(info, from, to, "sequence")
	for _, v := range list {
		if len(v) == 2 {
			ps := schema.DictionarySelectParam{
				ParentID: parentID,
				Sequence: v[0]["sequence"].(int),
			}
			items, e := a.DictionaryModel.QuerySelect(ps)
			if e == nil && len(items) == 1 {
				e = a.DictionaryModel.Update(items[0].RecordID, v[1])
			}
			if e != nil {
				return e
			}
		}
	}
	return nil
}

// GetLastSequence 获取最后排序
func (a *Dictionary) GetLastSequence(parentID string) int {
	result := 0
	ps := schema.DictionarySelectParam{
		ParentID: parentID,
	}
	items, _ := a.DictionaryModel.QuerySelect(ps)

	for _, v := range items {
		if v.Sequence > result {
			result = v.Sequence
		}
	}
	return result
}
